import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import java.awt.event.*;
import java.awt.*;
import java.sql.*;
import static java.lang.System.*;
import javax.swing.border.*;
/**
 *
 * @author ayakout
 */
public class OutputPanel extends JPanel {
    private int currentRowNum, rowCount;
    private DBConnector dbCon;
    private ArrayList<JComponent> fieldDirty = new ArrayList<JComponent>();
    private HashMap<JComponent,String> undoData = new HashMap<JComponent,String>();
    private JPanel bottomPanel = new JPanel();
    private JButton firstRecord = new JButton("|<<");
    private JButton lastRecord = new JButton(">>|");
    private JButton nextRecord = new JButton(">>");
    private JButton prevRecord = new JButton("<<");
    private JButton newRecord = new JButton(">>*");
    private JTextField recordDisplay = new JTextField(" 1 ");
    private JLabel lbl = new JLabel(" of ");
    private JLabel totalRecords = new JLabel();
    protected JPanel compPanel = new JPanel(null);
    String mainTable, mainFields;
    JTextField selectedTextField;
    private DBConnector.MyResultSet myrs;
    private boolean insertNewRecord, undoNewRecord, previousRecordUpdated, nextRecordUpdated;
    
    /** Creates a new instance of OutputPanel */
    public OutputPanel(DBConnector dbc, ArrayList<MyComponentContainer> componentList, Color backColor, Dimension panelDimension, int recordsLimit) {
        dbCon = dbc;
        currentRowNum = 1;
        setLayout(new BorderLayout());
        compPanel.setBackground(backColor);
        compPanel.setSize(panelDimension);
        
        // Setting record panel
        RecordNavigator rec = new RecordNavigator();
        recordDisplay.setEditable(false);
        firstRecord.addActionListener(rec);
        lastRecord.addActionListener(rec);
        nextRecord.addActionListener(rec);
        prevRecord.addActionListener(rec);
        newRecord.addActionListener(rec);
        firstRecord.setToolTipText("First record");
        lastRecord.setToolTipText("Last record");
        nextRecord.setToolTipText("Next record");
        prevRecord.setToolTipText("Previous record");
        newRecord.setToolTipText("New record");
        bottomPanel.add(new JLabel("Record : "));
        bottomPanel.add(firstRecord);
        bottomPanel.add(prevRecord);
        bottomPanel.add(recordDisplay);
        bottomPanel.add(nextRecord);
        bottomPanel.add(lastRecord);
        bottomPanel.add(newRecord);
        bottomPanel.add(lbl);
        bottomPanel.add(totalRecords);
        add(bottomPanel, BorderLayout.SOUTH);
        
        // Setting output view
        add(compPanel);
        
        // Adding components to panel and getting database information
        for (MyComponentContainer i : componentList) {
            if (i instanceof MyButtonContainer) {
                MyButtonContainer myButton = (MyButtonContainer)i;
                JButton designButton = (JButton)i.getComponent();
                JButton b = new JButton(designButton.getText());
                b.setLocation(designButton.getX(), designButton.getY());
                b.setSize(designButton.getWidth(), designButton.getHeight());
                b.setIcon(designButton.getIcon());
                // Checking button functionality
                // Adding button handler
                switch (myButton.getOperation()) {
                    case (MyButtonContainer.GoToNextRecord):
                        b.addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent e) {
                                // Next record action
                                navigateRecords(">>");
                            }
                        });
                        break;
                    case (MyButtonContainer.GoToPreviuosRecord):
                        b.addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent e) {
                                // Previous record action
                                navigateRecords("<<");
                            }
                        });
                        break;
                    case (MyButtonContainer.GoToFirstRecord):
                        b.addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent e) {
                                // First record action
                                navigateRecords("|<<");
                            }
                        });
                        break;
                    case (MyButtonContainer.GoToLastRecord):
                        b.addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent e) {
                                // Last record action
                                navigateRecords(">>|");
                            }
                        });
                        break;
                    case (MyButtonContainer.AddNewRecord):
                        b.addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent e) {
                                // Next record action
                                navigateRecords(">>*");
                            }
                        });
                        break;
                    case (MyButtonContainer.DeleteRecord):
                        b.addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent e) {
                                // Delete record action
                                String msg = "You are about to delete 1 record.\n\nIf you click Yes, you wont be able to undo this delete operation.\nAre you sure you want to delete this record?";
                                if(JOptionPane.showConfirmDialog(null, msg,"Confirm delete", JOptionPane.YES_NO_OPTION)==JOptionPane.OK_OPTION){
                                    deleteRecord();
                                }
                            }
                        });
                        break;
                    case (MyButtonContainer.UndoRecord):
                        b.addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent e) {
                                // Undo record action
                                undoRecord();
                            }
                        });
                        break;
                    case (MyButtonContainer.FindRecord):
                        b.addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent e) {
                                // Find record action
                                String[] fields = mainFields.split("\\,");
                                new FindRecordFrame(fields).setVisible(true);
                            }
                        });
                        break;
                }
                compPanel.add(b);
                
            } else if (i instanceof MyCheckBoxContainer) {
                MyCheckBoxContainer designMyCheckBox = (MyCheckBoxContainer)i;
                String[] fieldInfo = designMyCheckBox.getRelation().split("\\.");
                JCheckBox designCheckBox = (JCheckBox)i.getComponent();
                JCheckBox check = new JCheckBox();
                check.setSize(designCheckBox.getWidth(), designCheckBox.getHeight());
                check.setLocation(designCheckBox.getX(), designCheckBox.getY());
                check.setName(designMyCheckBox.getRelation());
                check.setBackground(((JCheckBox)designMyCheckBox.getComponent()).getBackground());
                check.setHorizontalAlignment(((JCheckBox)designMyCheckBox.getComponent()).getHorizontalAlignment());
                check.setVerticalAlignment(((JCheckBox)designMyCheckBox.getComponent()).getVerticalAlignment());
                check.setBorder(((JCheckBox)designMyCheckBox.getComponent()).getBorder());
                check.setForeground(((JCheckBox)designMyCheckBox.getComponent()).getForeground());
                if (mainFields == null) {
                    mainFields = fieldInfo[1];
                } else {
                    mainFields += "," + fieldInfo[1];
                }
                check.addMouseListener( new MouseAdapter() {
                    public void mousePressed(MouseEvent e) {
                        JCheckBox check = (JCheckBox)e.getComponent();
                        if (fieldDirty.contains(check) == false) {
                            //out.println("first time undo");
                            fieldDirty.add(check);
                            undoData.put(check, check.isSelected()? "true":"false");
                            //out.println("put undo data::"+text.getName());
                        }
                    }
                });
                compPanel.add(check);
                
            } else if (i instanceof MyComboBoxContainer) {                                                
                JComboBox designComboBox = (JComboBox)i.getComponent();
                Vector<StringBuilder> items = new Vector<StringBuilder>();
                Vector<String> comboItems = ((MyComboBoxContainer)i).getCustomizedTableData();
                if (comboItems == null) {                    
                    comboItems = dbCon.getColumn(((MyComboBoxContainer)i).getTableNameOutput(), ((MyComboBoxContainer)i).getArrangedColumnsNames()[0]);                    
                    for(int j=0;j<comboItems.size();j++){
                        items.add(new StringBuilder(comboItems.get(j)));
                    }
                    for(int j=1;j<((MyComboBoxContainer)i).getArrangedColumnsNames().length;j++){
                        Vector<String> moreItems = dbCon.getColumn(((MyComboBoxContainer)i).getTableNameOutput(), ((MyComboBoxContainer)i).getArrangedColumnsNames()[j]);                        
                        for(int k=0;k<comboItems.size();k++){                                                        
                            ((StringBuilder)items.get(k)).append(" "+moreItems.get(k));
                        }
                    }
                    for(int j=0;j<((MyComboBoxContainer)i).getAllColumnsNames().size();j++){
                        Vector<String> moreItems = dbCon.getColumn(((MyComboBoxContainer)i).getTableNameOutput(), ((MyComboBoxContainer)i).getArrangedColumnsNames()[j]);                        
                        for(int k=0;k<comboItems.size();k++){                            
                            ((StringBuilder)items.get(k)).append(" "+moreItems.get(k));
                        }
                    }                      
                }
                //for(StringBuilder s : items){System.out.println(s);}
                JComboBox comboBox = new JComboBox(items);
                comboBox.setName(((MyComboBoxContainer)i).getTableNameInput()+"."+((MyComboBoxContainer)i).getFieldNameInput());                
                comboBox.setSize(designComboBox.getWidth(), designComboBox.getHeight());
                comboBox.setLocation(designComboBox.getX(), designComboBox.getY());
                comboBox.setBackground(designComboBox.getBackground());                                
                //comboBox.setBorder(BorderFactory.createLineBorder(((LineBorder)designComboBox.getBorder()).getLineColor(),((MyLabelContainer)i).getBorderWidth()));
                comboBox.setForeground(designComboBox.getForeground());
                comboBox.setFont(designComboBox.getFont());  
                if (mainFields == null) {
                    mainFields = ((MyComboBoxContainer)i).getFieldNameInput();
                } else {
                    mainFields += "," + ((MyComboBoxContainer)i).getFieldNameInput();
                }                    
                              
                comboBox.addPopupMenuListener(new PopupMenuListener() {                        
                    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { 
                        JComboBox combo = (JComboBox)e.getSource();                                                
                        if (fieldDirty.contains(combo) == false) {                             
                            fieldDirty.add(combo);                            
                        }                        
                    }
                    public void popupMenuCanceled(PopupMenuEvent e) {                        
                    }                    
                    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {                        
                        JComboBox combo = (JComboBox)e.getSource();  
                        undoData.put(combo, Integer.toString(combo.getSelectedIndex()));  
                    }                    
                });
                compPanel.add(comboBox);
                
            } else if (i instanceof MyLabelContainer) {
                JLabel designLabel = (JLabel)i.getComponent();
                JLabel l = new JLabel(designLabel.getText());
                l.setLocation(designLabel.getX(), designLabel.getY());
                l.setSize(designLabel.getWidth(), designLabel.getHeight());
                l.setBackground(designLabel.getBackground());
                l.setHorizontalAlignment(designLabel.getHorizontalAlignment());
                l.setVerticalAlignment(designLabel.getVerticalAlignment());
                l.setBorder(BorderFactory.createLineBorder(((LineBorder)designLabel.getBorder()).getLineColor(),((MyLabelContainer)i).getBorderWidth()));
                l.setForeground(designLabel.getForeground());
                l.setFont(designLabel.getFont());
                l.setIcon(designLabel.getIcon());               
                compPanel.add(l);
                
            } else if (i instanceof MyListContainer) {
                /*
                JList designList = (JList)i.getComponent();
                Vector<String> listItems = ((MyListContainer)i).getListItems();
                if (listItems == null) {
                    listItems = dbCon.getColumn(((MyListContainer)i).getTable(), ((MyListContainer)i).getField());
                }
                JList list = new JList(listItems);
                JScrollPane scroll = new JScrollPane(list);
                scroll.setSize(designList.getWidth(), designList.getHeight());
                scroll.setLocation(designList.getX(), designList.getY());
                compPanel.add(scroll);
                 */
            } else if (i instanceof MyPictureContainer) {
                JLabel designPicture = (JLabel)i.getComponent();
                JLabel pic = new JLabel(designPicture.getIcon());
                pic.setLocation(designPicture.getX(), designPicture.getY());
                pic.setSize(designPicture.getWidth(), designPicture.getHeight());
                pic.setBackground(designPicture.getBackground());
                pic.setForeground(designPicture.getForeground());
                pic.setIcon(designPicture.getIcon());
                pic.setHorizontalAlignment(designPicture.getHorizontalAlignment());
                pic.setVerticalAlignment(designPicture.getVerticalAlignment());
                pic.setBorder(designPicture.getBorder());
                compPanel.add(pic);
                
            } else if (i instanceof MyRadioButtonContainer) {
                MyRadioButtonContainer designMyRadioButton = (MyRadioButtonContainer)i;
                String[] fieldInfo = designMyRadioButton.getRelation().split("\\.");
                JRadioButton designRadioButton = (JRadioButton)i.getComponent();
                JRadioButton radio = new JRadioButton();
                radio.setSize(designRadioButton.getWidth(), designRadioButton.getHeight());
                radio.setLocation(designRadioButton.getX(), designRadioButton.getY());
                radio.setBackground(designRadioButton.getBackground());
                radio.setForeground(designRadioButton.getForeground());
                radio.setHorizontalAlignment(designRadioButton.getHorizontalAlignment());
                radio.setVerticalAlignment(designRadioButton.getVerticalAlignment());
                radio.setBorder(designRadioButton.getBorder());
                radio.setName(designMyRadioButton.getRelation());
                if (mainFields == null) {
                    mainFields = fieldInfo[1];
                } else {
                    mainFields += "," + fieldInfo[1];
                }
                radio.addMouseListener( new MouseAdapter() {
                    public void mousePressed(MouseEvent e) {
                        JRadioButton radio = (JRadioButton)e.getComponent();
                        if (fieldDirty.contains(radio) == false) {
                            fieldDirty.add(radio);
                            undoData.put(radio, radio.isSelected()? "true":"false");
                            //out.println("put undo data::"+text.getName());
                        }
                    }
                });
                compPanel.add(radio);
                
            } else if (i instanceof MyTextFieldContainer) {
                JTextField designTextField = (JTextField)i.getComponent();
                String[] fieldInfo = designTextField.getText().split("\\.");
                assert fieldInfo.length == 2 : "Field not linked to database";
                // Building main table fields string
                if (mainTable == null) {
                    mainTable = fieldInfo[0];
                }
                if (mainFields == null) {
                    mainFields = fieldInfo[1];
                } else {
                    mainFields += "," + fieldInfo[1];
                }
                JTextField t = new JTextField();
                t.setLocation(designTextField.getX(), designTextField.getY());
                t.setSize(designTextField.getWidth(), designTextField.getHeight());
                t.setBackground(designTextField.getBackground());
                t.setForeground(designTextField.getForeground());
                t.setHorizontalAlignment(designTextField.getHorizontalAlignment());
                t.setBorder(designTextField.getBorder());
                t.setFont(designTextField.getFont());
                // Setting the text of the design textfield as the name of the
                // output textfield which contains database field information
                t.setName(designTextField.getText());
                // Set number of table rows
                if (rowCount == 0) {
                    rowCount = dbCon.getRowCount(fieldInfo[0]);
                    totalRecords.setText(Integer.toString(rowCount));
                }
                // map.put(t, dbCon.new MyResultSet(fieldInfo[0], fieldInfo[1]));
                // Setting dirty flag on field change
                t.addKeyListener(new KeyAdapter() {
                    public void keyPressed(KeyEvent e) {
                        JTextField text = (JTextField)e.getComponent();
                        if (fieldDirty.contains(text) == false) {
                            fieldDirty.add(text);
                            undoData.put(text, text.getText());
                            //out.println("put undo data::"+text.getName());
                        }
                    }
                });
                t.addMouseListener(new MouseAdapter(){
                    public void mouseClicked(MouseEvent e) {
                        selectedTextField = (JTextField)e.getComponent();
                    }
                });
                compPanel.add(t);
                
            } else if (i instanceof MyToggleButtonContainer) {
                JToggleButton designToggleButton = (JToggleButton)i.getComponent();
            }
        }
        
        // Get a result set
        myrs = dbCon.new MyResultSet(mainTable, mainFields, recordsLimit);
        
        // Setting initial values
        for (Component comp : OutputPanel.this.compPanel.getComponents()) {
            if (comp instanceof JTextField) {
                JTextField text = (JTextField)comp;
                String[]fieldInfo = text.getName().split("\\.");
                //System.out.println("Field::"+fieldInfo[1]+"AutoKey::"+myrs.getAutoKey());
                if (fieldInfo[1].equals(myrs.getAutoKey())) {
                    text.setEditable(false);
                }
                Object o = myrs.getValue(fieldInfo[1]);
                text.setText(o==null ? "":o.toString());
            } else if (comp instanceof JCheckBox) {
                JCheckBox check = (JCheckBox)comp;
                String[]fieldInfo = check.getName().split("\\.");
                Object o = myrs.getValue(fieldInfo[1]);
                check.setSelected(o==null||o.toString().equals("false") ? false:true);
            } else if (comp instanceof JRadioButton) {
                JRadioButton radio = (JRadioButton)comp;
                String[]fieldInfo = radio.getName().split("\\.");
                Object o = myrs.getValue(fieldInfo[1]);
                radio.setSelected(o==null||o.toString().equals("false") ? false:true);
            }
        }
    }
    //#########################################################################
    private class RecordNavigator implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            navigateRecords(e.getActionCommand());
        }
    }
    //#########################################################################
    /** Delete record action */
    void deleteRecord() {
        previousRecordUpdated = false;
        nextRecordUpdated =false;
        myrs.delete();
        myrs.next();
        myrs.previous();
        loadRecords();
        rowCount--;
        totalRecords.setText(Integer.toString(rowCount));
    }
    //#########################################################################
    /** One step undo, undo last action */
    void undoRecord() {
        
        if(previousRecordUpdated == true) {
            previousRecordUpdated = false;
            myrs.previous();
            //myrs.undo();
            for (Component comp : OutputPanel.this.compPanel.getComponents()) {
                if (comp instanceof JTextField) {
                    JTextField text = (JTextField)comp;
                    String[]fieldInfo = text.getName().split("\\.");
                    assert fieldInfo.length == 2 : "Field not linked to database";
                    // Get next value
                    if (undoData.containsKey(text)) {
                        text.setText(undoData.get(text));
                        fieldDirty.add(text);
                    } else {
                        Object o = myrs.getValue(fieldInfo[1]);
                        text.setText(o==null ? "":o.toString());
                    }
                } else if (comp instanceof JCheckBox) {
                    JCheckBox check = (JCheckBox)comp;
                    String[]fieldInfo = check.getName().split("\\.");
                    if (undoData.containsKey(check)) {
                        check.setSelected(new Boolean(undoData.get(check)));
                        fieldDirty.add(check);
                    } else {
                        Object o = myrs.getValue(fieldInfo[1]);
                        check.setSelected(o==null||o.toString().equals("false") ? false:true);
                    }
                } else if (comp instanceof JRadioButton) {
                    JRadioButton radio = (JRadioButton)comp;
                    String[]fieldInfo = radio.getName().split("\\.");
                    if (undoData.containsKey(radio)) {
                        radio.setSelected(new Boolean(undoData.get(radio)));
                        fieldDirty.add(radio);
                    } else {
                        Object o = myrs.getValue(fieldInfo[1]);
                        radio.setSelected(o==null||o.toString().equals("false") ? false:true);
                    }
                } else if (comp instanceof JComboBox) {
                    JComboBox combo = (JComboBox)comp;
                    String[]fieldInfo = combo.getName().split("\\.");
                    assert fieldInfo.length == 2 : "Field not linked to database";
                    
                    if (undoData.containsKey(combo)) {
                        combo.setSelectedIndex(Integer.parseInt(undoData.get(combo)));
                        fieldDirty.add(combo);
                    } else {
                        Object o = myrs.getValue(fieldInfo[1]);
                        for(int i=0;i<combo.getItemCount();i++) {
                           String[] arr = ((StringBuilder)combo.getItemAt(i)).toString().split(" ");                
                            if(arr[0].equals(o)) {
                                combo.setSelectedIndex(i);
                                break;
                            }
                        }
                    }
                }
            }
            updateRecord("");
            //fieldDirty.clear();
            currentRowNum--;
            recordDisplay.setText(Integer.toString(currentRowNum));            
            //out.println("undo updated prev field");
            
        } else if(nextRecordUpdated == true) {
            nextRecordUpdated = false;
            myrs.next();
            //myrs.undo();
            for (Component comp : OutputPanel.this.compPanel.getComponents()) {
                if (comp instanceof JTextField) {
                    JTextField text = (JTextField)comp;
                    String[]fieldInfo = text.getName().split("\\.");
                    assert fieldInfo.length == 2 : "Field not linked to database";
                    
                    if (undoData.containsKey(text)) {
                        text.setText(undoData.get(text));
                        fieldDirty.add(text);
                    } else {
                        Object o = myrs.getValue(fieldInfo[1]);
                        text.setText(o==null ? "":o.toString());
                    }
                } else if (comp instanceof JCheckBox) {
                    JCheckBox check = (JCheckBox)comp;
                    String[]fieldInfo = check.getName().split("\\.");
                    if (undoData.containsKey(check)) {
                        check.setSelected(new Boolean(undoData.get(check)));
                        fieldDirty.add(check);
                    } else {
                        Object o = myrs.getValue(fieldInfo[1]);
                        check.setSelected(o==null||o.toString().equals("false") ? false:true);
                    }
                } else if (comp instanceof JRadioButton) {
                    JRadioButton radio = (JRadioButton)comp;
                    String[]fieldInfo = radio.getName().split("\\.");
                    if (undoData.containsKey(radio)) {
                        radio.setSelected(new Boolean(undoData.get(radio)));
                        fieldDirty.add(radio);
                    } else {
                        Object o = myrs.getValue(fieldInfo[1]);
                        radio.setSelected(o==null||o.toString().equals("false") ? false:true);
                    }
                } else if (comp instanceof JComboBox) {
                    JComboBox combo = (JComboBox)comp;
                    String[]fieldInfo = combo.getName().split("\\.");
                    assert fieldInfo.length == 2 : "Field not linked to database";
                    
                    if (undoData.containsKey(combo)) {
                        combo.setSelectedIndex(Integer.parseInt(undoData.get(combo)));
                        fieldDirty.add(combo);
                    } else {
                        Object o = myrs.getValue(fieldInfo[1]);
                        for(int i=0;i<combo.getItemCount();i++) {
                           String[] arr = ((StringBuilder)combo.getItemAt(i)).toString().split(" ");                
                            if(arr[0].equals(o)) {
                                combo.setSelectedIndex(i);
                                break;
                            }
                        }
                    }
                }
            }
            updateRecord("");
            //fieldDirty.clear();
            currentRowNum++;
            recordDisplay.setText(Integer.toString(currentRowNum));            
            //out.println("undo updated next field");
            
        } else if (fieldDirty.size() > 0) { // Undo typed text
            for (Component comp : OutputPanel.this.compPanel.getComponents()) {
                if (fieldDirty.contains(comp)) {
                    if (comp instanceof JTextField) {
                        JTextField text = (JTextField)comp;
                        text.setText(undoData.get(text));
                    } else if (comp instanceof JCheckBox) {
                        JCheckBox check = (JCheckBox)comp;
                        //out.println("checkbox "+undoData.get(check));
                        check.setSelected(new Boolean(undoData.get(check)));
                    } else if (comp instanceof JRadioButton) {
                        JRadioButton radio = (JRadioButton)comp;
                        radio.setSelected(new Boolean(undoData.get(radio)));
                    } else if (comp instanceof JComboBox) {
                        JComboBox combo = (JComboBox)comp;                        
                        combo.setSelectedIndex(Integer.parseInt(undoData.get(combo)));
                    }
                }
            }
            fieldDirty.clear();
            //out.println("undo typing");
        }
        undoData.clear();
    }
    //#########################################################################
    /** Load records at startup */
    private void loadRecords() {
        for (Component comp : OutputPanel.this.compPanel.getComponents()) {
            if (comp instanceof JTextField) {
                JTextField text = (JTextField)comp;
                String[]fieldInfo = text.getName().split("\\.");
                assert fieldInfo.length == 2 : "Field not linked to database";
                // Get next value
                Object o = myrs.getValue(fieldInfo[1]);
                text.setText(o==null ? "":o.toString());
            } else if (comp instanceof JCheckBox) {
                JCheckBox check = (JCheckBox)comp;
                String[] fieldInfo = comp.getName().split("\\.");
                Object o = myrs.getValue(fieldInfo[1]);
                check.setSelected(o==null||o.toString().equals("false") ? false:true);
            } else if (comp instanceof JRadioButton) {
                JRadioButton radio = (JRadioButton)comp;
                String[] fieldInfo = comp.getName().split("\\.");
                Object o = myrs.getValue(fieldInfo[1]);
                radio.setSelected(o==null||o.toString().equals("false") ? false:true);
            } else if (comp instanceof JComboBox) {
                JComboBox combo = (JComboBox)comp;
                String[] fieldInfo = comp.getName().split("\\.");
                Object o = myrs.getValue(fieldInfo[1]);                
                for(int i=0;i<combo.getItemCount();i++) {
                    String[] arr = ((StringBuilder)combo.getItemAt(i)).toString().split(" ");                
                    if(arr[0].equals(o)) {
                        combo.setSelectedIndex(i);
                        break;
                    }
                }
            }
        }
    }
    //#########################################################################
    /** Navigate through records according to direction string */
    void navigateRecords(String action) {
        previousRecordUpdated = false;
        nextRecordUpdated =false;
        if ((action.equals("<<") || action.equals("|<<"))
        && fieldDirty.size()==0 && insertNewRecord) {
            insertNewRecord = false;
            undoNewRecord = true;
        } else {
            // Checking record integrity
            for (Component comp : OutputPanel.this.compPanel.getComponents()) {
                if (comp instanceof JTextField) {
                    JTextField text = (JTextField)comp;
                    String[]fieldInfo = text.getName().split("\\.");
                    if (text.getText().equals("") && myrs.getNotNullFields().contains(fieldInfo[1])) {
                        JOptionPane.showMessageDialog(null, fieldInfo[1]+" field required");
                        return;
                    }
                }
            }
            // Update or insert new record
            if (insertNewRecord == true) {
                insertNewRecord = false;
                HashMap<String, String> record = new HashMap<String, String>();
                for (Component comp : OutputPanel.this.compPanel.getComponents()) {
                    if (comp instanceof JTextField) {
                        JTextField text = (JTextField)comp;
                        String[]fieldInfo = text.getName().split("\\.");
                        assert fieldInfo.length == 2 : "Field not linked to database";
                        record.put(fieldInfo[1], text.getText());
                    } else if (comp instanceof JCheckBox) {
                        JCheckBox check = (JCheckBox)comp;
                        String[] fieldInfo = comp.getName().split("\\.");
                        String value = check.isSelected()? "1":"0";
                        record.put(fieldInfo[1], value);
                    } else if (comp instanceof JRadioButton) {
                        JRadioButton radio = (JRadioButton)comp;
                        String[] fieldInfo = comp.getName().split("\\.");
                        String value = radio.isSelected()? "1":"0";
                        record.put(fieldInfo[1], value);
                    } else if (comp instanceof JComboBox) {
                        JComboBox combo = (JComboBox)comp;
                        String[] fieldInfo = combo.getName().split("\\.");
                        record.put(fieldInfo[1], ((StringBuilder)combo.getSelectedItem()).toString().split(" ")[0]);
                    }
                }
                try {
                    myrs.insert(record);
                    rowCount++;
                    totalRecords.setText(Integer.toString(rowCount));
                } catch(SQLException ex){
                    JOptionPane.showMessageDialog(null,ex.getMessage());
                    navigateRecords(">>|");
                } finally {
                    fieldDirty.clear();
                }
            } else {
                updateRecord(action);
            }
        }
        // Load new record values
        if (action.equals(">>")) {
            // Next record action
            if (currentRowNum < rowCount) {
                myrs.next();
                loadRecords();
                currentRowNum++;
            }
        } else if (action.equals("<<")) {
            // Previous record action
            if (currentRowNum > 1) {
                if (undoNewRecord == false) {
                    myrs.previous();
                } else {
                    undoNewRecord = false;
                }
                loadRecords();
                currentRowNum--;
            }
        } else if (action.equals("|<<")) {
            // First record action
            undoNewRecord = false;
            myrs.first();
            loadRecords();
            currentRowNum = 1;
            
        } else if (action.equals(">>|")) {
            // Last record action
            myrs.last();
            loadRecords();
            currentRowNum = rowCount;
        } else if (action.equals(">>*")) {
            // insert new record
            for (Component comp : OutputPanel.this.compPanel.getComponents()) {
                if (comp instanceof JTextField) {
                    JTextField text = (JTextField)comp;
                    String[]fieldInfo = text.getName().split("\\.");
                    if (fieldInfo[1].equals(myrs.getAutoKey())) {
                        text.setText("auto-increment");
                    } else {
                        text.setText("");
                    }
                }
            }
            insertNewRecord = true;
            //rowCount++;
            currentRowNum = rowCount+1;
            myrs.last();
        }
        recordDisplay.setText(Integer.toString(currentRowNum));        
    }
    //#########################################################################
    /** Update record action */
    void updateRecord(String direction) {
        if (fieldDirty.size() > 0) {
            //out.println("updating...");
            if (direction.equals(">>")) {
                previousRecordUpdated = true;
            } else if (direction.equals("<<")) {
                nextRecordUpdated = true;
            }
            HashMap<String, String> record = new HashMap<String, String>();
            for (Component comp : OutputPanel.this.compPanel.getComponents()) {
                if (fieldDirty.contains(comp)) {
                    if (comp instanceof JTextField) {
                        JTextField text = (JTextField)comp;
                        String[]fieldInfo = text.getName().split("\\.");
                        assert fieldInfo.length == 2 : "Field not linked to database";
                        // Update changed values in database
                        record.put(fieldInfo[1], text.getText());
                        //myrs.setUpdated(true);
                    } else if (comp instanceof JCheckBox) {
                        JCheckBox check = (JCheckBox)comp;
                        String[] fieldInfo = check.getName().split("\\.");
                        record.put(fieldInfo[1], check.isSelected()? "1":"0");
                    } else if (comp instanceof JRadioButton) {
                        JRadioButton radio = (JRadioButton)comp;
                        String[] fieldInfo = radio.getName().split("\\.");
                        record.put(fieldInfo[1], radio.isSelected()? "1":"0");
                    } else if (comp instanceof JComboBox) {
                        JComboBox combo = (JComboBox)comp;
                        String[] fieldInfo = combo.getName().split("\\.");                        
                        record.put(fieldInfo[1], ((StringBuilder)combo.getSelectedItem()).toString().split(" ")[0]);
                    }
                }
            }
            myrs.update(record);
            fieldDirty.clear();
        }
    }
    //#########################################################################    
    class FindRecordFrame extends javax.swing.JFrame {
        
        /** Creates new form FindRecordFrame */
        public FindRecordFrame(String[] comboData) {
            this.setTitle("Find");
            initComponents();
            for(String s : comboData) {
                jComboBox1.addItem(s);
            }
        }
        
        /** This method is called from within the constructor to
         * initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is
         * always regenerated by the Form Editor.
         */
        // <editor-fold defaultstate="collapsed" desc=" Generated Code ">
        private void initComponents() {
            jComboBox1 = new javax.swing.JComboBox();
            jTextField1 = new javax.swing.JTextField();
            jLabel1 = new javax.swing.JLabel();
            jLabel2 = new javax.swing.JLabel();
            jButton1 = new javax.swing.JButton();
            jButton2 = new javax.swing.JButton();
            jLabel3 = new javax.swing.JLabel();
            jComboBox2 = new javax.swing.JComboBox();
            jButton3 = new javax.swing.JButton();
            
            setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
            
            jComboBox1.addItemListener(new java.awt.event.ItemListener() {
                public void itemStateChanged(java.awt.event.ItemEvent evt) {
                    jComboBox1ItemStateChanged(evt);
                }
            });
            
            jTextField1.addKeyListener(new java.awt.event.KeyAdapter() {
                public void keyReleased(java.awt.event.KeyEvent evt) {
                    jTextField1KeyReleased(evt);
                }
            });
            
            jLabel1.setText("Field:");
            
            jLabel2.setText("Find what:");
            
            jButton1.setText("Find");
            jButton1.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton1ActionPerformed(evt);
                }
            });
            
            jButton2.setText("Cancel");
            jButton2.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton2ActionPerformed(evt);
                }
            });
            
            jLabel3.setText("Match:");
            
            jComboBox2.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Whole field", "Any part of field", "Start of field" }));
            jComboBox2.addItemListener(new java.awt.event.ItemListener() {
                public void itemStateChanged(java.awt.event.ItemEvent evt) {
                    jComboBox2ItemStateChanged(evt);
                }
            });
            
            jButton3.setText("Find Next");
            jButton3.setEnabled(false);
            jButton3.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton3ActionPerformed(evt);
                }
            });
            
            org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                    layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(layout.createSequentialGroup()
                    .addContainerGap()
                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, jLabel3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, jLabel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, jLabel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(layout.createSequentialGroup()
                    .add(jButton1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 73, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(jButton3)
                    .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                    .add(jButton2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 75, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jTextField1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 253, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jComboBox1, 0, 253, Short.MAX_VALUE)
                    .add(jComboBox2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                    .addContainerGap())
                    );
            layout.setVerticalGroup(
                    layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(layout.createSequentialGroup()
                    .addContainerGap()
                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jLabel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE)
                    .add(jComboBox1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jLabel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 19, Short.MAX_VALUE)
                    .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel3)
                    .add(jComboBox2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                    .add(8, 8, 8)
                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jButton1)
                    .add(jButton2)
                    .add(jButton3))
                    .addContainerGap())
                    );
            pack();
        }// </editor-fold>
        private void jComboBox1ItemStateChanged(java.awt.event.ItemEvent evt) {
            // TODO add your handling code here:
            jButton3.setEnabled(false);
        }
        
        private void jTextField1KeyReleased(java.awt.event.KeyEvent evt) {
            // TODO add your handling code here:
            jButton3.setEnabled(false);
        }
        
        private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
            // TODO add your handling code here:
            if(myrs.findNext((String)jComboBox1.getSelectedItem(), jTextField1.getText(), jComboBox2.getSelectedIndex())) {
                /*
                for (Component comp : OutputPanel.this.compPanel.getComponents()) {
                    if (comp instanceof JTextField) {
                        JTextField text = (JTextField)comp;
                        String[]fieldInfo = text.getName().split("\\.");
                        assert fieldInfo.length == 2 : "Field not linked to database";
                        // Get next value
                        Object o = myrs.getValue(fieldInfo[1]);
                        text.setText(o==null ? "":o.toString());
                    }
                }
                 */
                loadRecords();
                currentRowNum = myrs.getCurrentRowNum();
                recordDisplay.setText(Integer.toString(currentRowNum));                
            } else {
                jButton3.setEnabled(false);
            }
        }
        
        private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
            // TODO add your handling code here:
            if (myrs.find((String)jComboBox1.getSelectedItem(), jTextField1.getText(), jComboBox2.getSelectedIndex())) {
                /*
                for (Component comp : OutputPanel.this.compPanel.getComponents()) {
                    if (comp instanceof JTextField) {
                        JTextField text = (JTextField)comp;
                        String[]fieldInfo = text.getName().split("\\.");
                        assert fieldInfo.length == 2 : "Field not linked to database";
                        // Get next value
                        Object o = myrs.getValue(fieldInfo[1]);
                        text.setText(o==null ? "":o.toString());
                    }
                }
                 */
                loadRecords();
                currentRowNum = myrs.getCurrentRowNum();
                recordDisplay.setText(Integer.toString(currentRowNum));                
                jButton3.setEnabled(true);
            } else {
                JOptionPane.showMessageDialog(null, "Not found");
            }
        }
        
        private void jComboBox2ItemStateChanged(java.awt.event.ItemEvent evt) {
            // TODO add your handling code here:
            jButton3.setEnabled(false);
        }
        
        private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
            // TODO add your handling code here:
            dispose();
        }
        
        /**
         * @param args the command line arguments
         */
        /*
        public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new FindRecordFrame().setVisible(true);
                }
            });
        }
         */
        
        // Variables declaration - do not modify
        private javax.swing.JButton jButton1;
        private javax.swing.JButton jButton2;
        private javax.swing.JButton jButton3;
        private javax.swing.JComboBox jComboBox1;
        private javax.swing.JComboBox jComboBox2;
        private javax.swing.JLabel jLabel1;
        private javax.swing.JLabel jLabel2;
        private javax.swing.JLabel jLabel3;
        private javax.swing.JTextField jTextField1;
        // End of variables declaration
        
    }
}
